/**
 * Copyright 2007-2010 非也
 * All rights reserved. 
 * 
 * This library is free software; you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License v3 as published by the Free Software
 * Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License along
 * with this library; if not, see http://www.gnu.org/licenses/lgpl.html.
 *
 */
package org.fireflow2.designer.eclipse.modelwrapper.basic;

import java.util.List;

import org.fireflow.model.process.WorkflowElement;
import org.fireflow.pdl.fpdl20.diagram.ActivityShape;
import org.fireflow.pdl.fpdl20.diagram.CommentShape;
import org.fireflow.pdl.fpdl20.diagram.DiagramElement;
import org.fireflow.pdl.fpdl20.diagram.EndNodeShape;
import org.fireflow.pdl.fpdl20.diagram.Fpdl20DiagramElement;
import org.fireflow.pdl.fpdl20.diagram.GroupShape;
import org.fireflow.pdl.fpdl20.diagram.RouterShape;
import org.fireflow.pdl.fpdl20.diagram.StartNodeShape;
import org.fireflow.pdl.fpdl20.diagram.WorkflowNodeShape;
import org.fireflow.pdl.fpdl20.process.Activity;
import org.fireflow.pdl.fpdl20.process.EndNode;
import org.fireflow.pdl.fpdl20.process.Router;
import org.fireflow.pdl.fpdl20.process.StartNode;
import org.fireflow.pdl.fpdl20.process.SubProcess;
import org.fireflow2.designer.eclipse.modelwrapper.ModelWrapper;
import org.fireflow2.designer.eclipse.modelwrapper.NodeWrapper;
import org.fireflow2.designer.eclipse.modelwrapper.SubProcessWrapper;
import org.fireflow2.designer.eclipse.modelwrapper.Wrapper;

/**
 *
 * @author 非也 nychen2000@163.com
 * Fire Workflow 官方网站：www.firesoa.com 或者 www.fireflow.org
 *
 */
public class GroupWrapper extends NodeWrapper {
	public GroupWrapper(SubProcessWrapper subflowWrapper,DiagramElement diagramElement) {
		super(subflowWrapper,null, diagramElement);

		initNodes();
	}
	
	protected void initNodes(){
		GroupShape groupShape = (GroupShape)this.getDiagramElement();
		SubProcess subflow = (SubProcess)this.subProcessWrapper.getWorkflowModelElement();
		
		List<WorkflowNodeShape> nodeShapeList = groupShape.getWorkflowNodeShapes();
		if (nodeShapeList!=null){
			for (WorkflowNodeShape nodeShape : nodeShapeList){
				String wfElmID = nodeShape.getWorkflowElementRef();
				
				WorkflowElement wfElm = subflow.findWFElementById(wfElmID);
				ModelWrapper modelWrapper = null;
				if (nodeShape instanceof StartNodeShape){
					modelWrapper = new StartNodeWrapper(subProcessWrapper,(StartNode)wfElm,nodeShape);
					subProcessWrapper.getStartNodesWrapper().addChild((StartNodeWrapper)modelWrapper);
				}
				else if (nodeShape instanceof ActivityShape){
					modelWrapper = new ActivityWrapper(subProcessWrapper,(Activity)wfElm,nodeShape);
					subProcessWrapper.getActivitiesWrapper().addChild((ActivityWrapper)modelWrapper);
				}
				else if (nodeShape instanceof RouterShape){
					modelWrapper = new RouterWrapper(subProcessWrapper,(Router)wfElm,nodeShape);
					subProcessWrapper.getRoutersWrapper().addChild((RouterWrapper)modelWrapper);
				}
				else if (nodeShape instanceof EndNodeShape){
					modelWrapper = new EndNodeWrapper(subProcessWrapper,(EndNode)wfElm,nodeShape);
					subProcessWrapper.getEndNodesWrapper().addChild((EndNodeWrapper)modelWrapper);
				}
				else if (nodeShape instanceof CommentShape){
					modelWrapper = new CommentWrapper(subProcessWrapper,(CommentShape)nodeShape);
				}
	
				if (modelWrapper!=null){
					modelWrapper.setParent(this);
					this.getChildren().add(modelWrapper);
					subProcessWrapper.putToSnModelWrapperMap(modelWrapper.getSn(), modelWrapper);					

				}

			}
		}
		

	}
	
	/* 所有的connector放在diagram里面
	public void initConnectors(){
		GroupShape groupShape = (GroupShape)this.getDiagramElement();
		ModelWrapper parent = (ModelWrapper)this.getParent();
		SubProcessWrapper parentWrapper = null;
		if (parent instanceof SubProcessWrapper){
			parentWrapper = (SubProcessWrapper)parent;
		}
		else if (parent instanceof PoolWrapper){
			parentWrapper = (SubProcessWrapper)parent.getParent();
		}
		if (parentWrapper==null) return;//模型不正确，无法初始化
		
		List<TransitionShape> transitionShapeList = groupShape.getTransitions();
		if (transitionShapeList!=null){
			for (TransitionShape transShape : transitionShapeList){
				Transition trans = subflow.getTransition(transShape.getWorkflowElementRef());
				TransitionWrapper transWrapper = new TransitionWrapper(trans,transShape);
				
				String fromNodeSN = transShape.getFromWorkflowNodeShape()==null?"":transShape.getFromWorkflowNodeShape().getSn();
				String toNodeSN = transShape.getToWorkflowNodeShape()==null?"":transShape.getToWorkflowNodeShape().getSn();
				NodeWrapper source = (NodeWrapper)parentWrapper.sn_modelwrapper_map.get(fromNodeSN);
				NodeWrapper target = (NodeWrapper)parentWrapper.sn_modelwrapper_map.get(toNodeSN);
				if (source!=null) {
					source.setLeavingTransition(transWrapper);
					transWrapper.setSource(source);
				}
				if (target!=null){
					target.setEnteringTransition(transWrapper);
					transWrapper.setTarget(target);
				}

				transWrapper.setParent(this);	
				allChildren.add(transWrapper);
				parentWrapper.sn_modelwrapper_map.put(transWrapper.getSn(), transWrapper);				
				parentWrapper.transitionsWrapper.set(transWrapper);
			}
		}
	}
	*/
	public void orphanChild(Wrapper child){
		GroupShape groupShape = (GroupShape)this.getDiagramElement();
		if (child instanceof StartNodeWrapper ||
				child instanceof EndNodeWrapper ||
				child instanceof RouterWrapper ||
				child instanceof ActivityWrapper){
			groupShape.getWorkflowNodeShapes().remove(((NodeWrapper)child).getDiagramElement());
		}
		else if (child instanceof CommentWrapper){
			groupShape.getComments().remove(((NodeWrapper)child).getDiagramElement());
		}
		super.orphanChild(child);
	}
	
	public void acceptChild(Wrapper wrapper){
		if (!(wrapper instanceof NodeWrapper))return;
		NodeWrapper child = (NodeWrapper)wrapper;
		wrapper.setParent(this);
		GroupShape groupshape = (GroupShape)this.getDiagramElement();

		if (child instanceof StartNodeWrapper ||
				child instanceof EndNodeWrapper ||
				child instanceof RouterWrapper ||
				child instanceof ActivityWrapper){
			groupshape.addWorkflowNodeShape((WorkflowNodeShape)child.getDiagramElement());
		}
		else if (child instanceof CommentWrapper){
			groupshape.addComment((CommentShape)child.getDiagramElement());
		}
		
		this.addChild(child,-1);
	}

	
	public void addChild(Wrapper child,int index){
		child.setParent(this);
		SubProcess subflow = (SubProcess)getSubProcessWrapper().getWorkflowModelElement();
		GroupShape groupShape = (GroupShape)this.getDiagramElement();
		
		if (child instanceof ActivityWrapper){
			Activity node = (Activity)((ActivityWrapper)child).getWorkflowModelElement();
			subflow.getActivities().add(node);
			groupShape.addWorkflowNodeShape((WorkflowNodeShape)((ModelWrapper) child).getDiagramElement());
		
			subProcessWrapper.getActivitiesWrapper().addChild(child);
		}else if (child instanceof RouterWrapper){
			Router node = (Router)((RouterWrapper)child).getWorkflowModelElement();
			subflow.getRouters().add(node);
			groupShape.addWorkflowNodeShape((WorkflowNodeShape)((ModelWrapper) child).getDiagramElement());
			subProcessWrapper.getRoutersWrapper().addChild(child);
		}else if (child instanceof StartNodeWrapper){
			StartNode node = (StartNode)((StartNodeWrapper)child).getWorkflowModelElement();
			subflow.getStartNodes().add(node);
			groupShape.addWorkflowNodeShape((WorkflowNodeShape)((ModelWrapper) child).getDiagramElement());
			subProcessWrapper.getStartNodesWrapper().addChild(child);
		}else if (child instanceof EndNodeWrapper){
			EndNode node = (EndNode)((EndNodeWrapper)child).getWorkflowModelElement();
			subflow.getEndNodes().add(node);
			groupShape.addWorkflowNodeShape((WorkflowNodeShape)((ModelWrapper) child).getDiagramElement());
			subProcessWrapper.getEndNodesWrapper().addChild(child);
		}else if (child instanceof CommentWrapper){
			CommentShape elm = (CommentShape)((EndNodeWrapper)child).getDiagramElement();
			groupShape.addComment(elm);
		}else if (child instanceof ServiceDefWrapper){
			this.getParent().addChild(child, index);
		}
		subProcessWrapper.putToSnModelWrapperMap(child.getSn(), child);
		super.addChild(child,index);
	}
	
	public void deleteChild(ModelWrapper child){
		child.setParent(null);
		SubProcess subflow = (SubProcess)subProcessWrapper.getWorkflowModelElement();
		GroupShape groupShape = (GroupShape)this.getDiagramElement();
		
		if (child instanceof ActivityWrapper){
			Activity node = (Activity)((ActivityWrapper)child).getWorkflowModelElement();
			subflow.getActivities().remove(node);
			groupShape.getWorkflowNodeShapes().remove((WorkflowNodeShape)((ModelWrapper) child).getDiagramElement());
			subProcessWrapper.getActivitiesWrapper().deleteChild(child);
		}else if (child instanceof RouterWrapper){
			Router node = (Router)((RouterWrapper)child).getWorkflowModelElement();
			subflow.getRouters().remove(node);
			groupShape.getWorkflowNodeShapes().remove((WorkflowNodeShape)((ModelWrapper) child).getDiagramElement());
			subProcessWrapper.getRoutersWrapper().deleteChild(child);
		}else if (child instanceof StartNodeWrapper){
			StartNode node = (StartNode)((StartNodeWrapper)child).getWorkflowModelElement();
			subflow.getStartNodes().remove(node);
			groupShape.getWorkflowNodeShapes().remove((WorkflowNodeShape)((ModelWrapper) child).getDiagramElement());
			subProcessWrapper.getStartNodesWrapper().deleteChild(child);
		}else if (child instanceof EndNodeWrapper){
			EndNode node = (EndNode)((EndNodeWrapper)child).getWorkflowModelElement();
			subflow.getEndNodes().remove(node);
			groupShape.getWorkflowNodeShapes().remove((WorkflowNodeShape)((ModelWrapper) child).getDiagramElement());
			subProcessWrapper.getEndNodesWrapper().deleteChild(child);
		}else if (child instanceof CommentWrapper){
			CommentShape elm = (CommentShape)((EndNodeWrapper)child).getDiagramElement();
			groupShape.getComments().remove(elm);
		}else if (child instanceof ServiceDefWrapper){
			this.getParent().deleteChild(child);
		}
		
		subProcessWrapper.removeFromSnModelWrapperMap(child.getSn());
		super.deleteChild(child);
	}
	/* (non-Javadoc)
	 * @see org.fireflow2.designer.eclipse.modelwrapper.AbsWrapper#getElementType()
	 */
	@Override
	public String getElementType() {
		return Fpdl20DiagramElement.GROUP.name();
	}

}
